package com.myproject.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.locks.ReentrantLock;

@RestController
@RequestMapping("/thread")
public class ThreadStateController {

    public static Object obj = new Object();
    public static Object obj1 = new Object();
    public static Object obj2 = new Object();
    public static ReentrantLock lock = new ReentrantLock();
    private static final Logger logger = LoggerFactory.getLogger(ThreadStateController.class);


    //死锁 wait sleep分别对应的状态
    //sleep
    @GetMapping("/sleepState")
    public String method1(String string){

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String state = thread.getState().toString();
        return state;
    }

    //wait
    @GetMapping("/waitState")
    public String method2(String string){

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj){
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("wait over");
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return thread.getState().toString();
    }


    //deadlock
    @GetMapping("/deadlockState")
    public String method3(String string) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                String name = Thread.currentThread().getName();
                synchronized (obj1){
                    System.out.println(name+" get lock1, try to get lock2");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (obj2){
                        System.out.println(name+" get lock2");
                    }

                }

                System.out.println(name+" over");
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                String name = Thread.currentThread().getName();

                synchronized (obj2){
                    System.out.println(name+" get lock2, try to get lock1");

                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    synchronized (obj1){
                        System.out.println(name+" get lock1");
                    }
                }

                System.out.println(name+" over");
            }
        });

        t1.start();
        t2.start();

        Thread.sleep(10000);
        return t1.getState().toString();
    }

    //new
    @GetMapping("/newState")
    public String method4(String string){

        Thread thread = new Thread();

        return thread.getState().toString();
    }

    //run
    @GetMapping("/runState")
    public String method5(String string) throws InterruptedException {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){}
            }
        });
        thread.start();
        Thread.sleep(3000);

        return thread.getState().toString();
    }

    //run
    @GetMapping("/terminatedState")
    public String method6(String string) throws InterruptedException {

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("over");
            }
        });
        thread.start();
        thread.join();

        return thread.getState().toString();
    }

    @GetMapping("/reentrantLockState")
    public String method7(String string) throws InterruptedException {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                lock.unlock();
            }
        });
        t1.start();

        Thread.sleep(1000);
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                lock.unlock();
            }
        });
        t2.start();
        Thread.sleep(1000);

        return t2.getState().toString();
    }

    //wait
    @GetMapping("/notify")
    public String method10(String string){

        synchronized (obj){
            obj.notify();
            System.out.println("notify over");
        }

        return "notify over";
    }


    //controller中启动其他线程
    @GetMapping("/method2")
    public String method50(String string){

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true){
                    count++;
                    /*try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }*/
                    System.out.println(Thread.currentThread().getName()+" hello "+count);
                    if (count==100){
                        break;
                    }
                }
            }
        });
        thread.start();
        System.out.println("method2");

        return "method2..";
    }




}
